package com.qkl.user.handler;

import com.qkl.user.dto.ExceptionResponse;
import com.qkl.user.enums.ExceptionEnum;
import com.qkl.user.exception.OperationException;
import com.qkl.user.exception.UserAlreadyExistsException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.stereotype.Component;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;

@Slf4j
@Component
@ControllerAdvice
public class GlobalExceptionHandler {
    // 处理自定义异常（最常用，放在最前面）
    @ExceptionHandler(OperationException.class)
    public ResponseEntity<ExceptionResponse> handleCustomException(OperationException ex) {
        // 日志分级：业务异常一般为WARN级别，避免淹没真正的错误日志
        //log.warn("Custom exception occurred: [code={}, message={}]", ex.getCode(), ex.getMessage());
        log.info("OperationException={}", ex.getMessage());
        ExceptionResponse response = new ExceptionResponse(
                ex.getCode(),
                ex.getMessage(),
                ex.getData()
        );

        HttpStatus status = HttpStatus.ACCEPTED;
        return new ResponseEntity<>(response, status);
    }

    // 处理用户已存在异常
    @ExceptionHandler(UserAlreadyExistsException.class)
    public ResponseEntity<String> handleUserAlreadyExists(UserAlreadyExistsException e) {
        return new ResponseEntity<>(e.getMessage(), HttpStatus.CONFLICT);
    }

    // 处理用户名密码错误
    @ExceptionHandler(BadCredentialsException.class)
    public ResponseEntity<ExceptionResponse> handleBadCredentials(BadCredentialsException ex) {
//        log.error("用户或者密码错误: {}", ex.getMessage());
        ExceptionEnum exceptionEnum = ExceptionEnum.LOGIN_FAILED;
        ExceptionResponse response = new ExceptionResponse(
                exceptionEnum.getCode(),
                exceptionEnum.getMsg()
        );
        return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
    }


    // 处理通用异常
    @ExceptionHandler(Exception.class)
    public ResponseEntity<ExceptionResponse> handleGeneralException(Exception ex) {
        log.info("通用系统错误: {},{}",ex.getMessage(),ex.getStackTrace());

        ExceptionEnum exceptionEnum = ExceptionEnum.INTERNAL_SERVER_ERROR;
        ExceptionResponse response = new ExceptionResponse(
                exceptionEnum.getCode(),
                exceptionEnum.getMsg()
        );
        return new ResponseEntity<>(response, HttpStatus.INTERNAL_SERVER_ERROR);
    }
    //请求格式问题
    @ExceptionHandler({HttpMessageNotReadableException.class, HttpMediaTypeNotSupportedException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseEntity<ExceptionResponse> handleHttpMessageNotReadableException() {
        ExceptionEnum exceptionEnum = ExceptionEnum.REQUEST_FORMAT;
        ExceptionResponse response = new ExceptionResponse(
                exceptionEnum
        );
        HttpStatus status = HttpStatus.BAD_REQUEST;
        return new ResponseEntity<>(response, status);
    }
    // 处理请求参数校验异常
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<ExceptionResponse> handleValidationExceptions(MethodArgumentNotValidException ex) {
        log.info("ValidationException={}", ex.getBindingResult().getAllErrors());
        String firstErrorMessage;
        // 获取第一个错误（无论字段级还是类级）
        if(ex.getFieldError() == null){ //自定义注解
             firstErrorMessage = ex.getBindingResult().getAllErrors().getFirst().getDefaultMessage();
        }else {
             firstErrorMessage = ex.getFieldError().getDefaultMessage();
        }
        ExceptionEnum exceptionEnum = ExceptionEnum.DATA_VALIDATION_FAILED;
        ExceptionResponse response = new ExceptionResponse(
                exceptionEnum.getCode(),
                firstErrorMessage
        );
        return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
    }
}
